package service

import (
	"db2_ddl_search/db2"
	"fmt"

	//"fmt"
	"os"

	//es客户端
	"context"
	"db2_ddl_search/es"
	"encoding/json"

	"github.com/gohouse/gorose/v2"
	"github.com/olivere/elastic/v7"
	log "github.com/sirupsen/logrus"
)

//保存索引
func SaveEsIndex() {

	ctx := context.Background()
	//索引名
	indexname := os.Getenv("ESINDEX")
	//对象列表
	objects, err := db2.GetObjects()

	if err == nil {
		if objects != nil && len(objects) > 0 {

			_, err = es.EsClient.DeleteIndex(indexname).Do(ctx)
			if err != nil {
				log.Error("删除失败" + err.Error())
			}

			exists, err := es.EsClient.IndexExists(indexname).Do(ctx)
			if err != nil || !exists {
				createIndex, err := es.EsClient.CreateIndex(indexname).Do(ctx)
				if err != nil {
					log.Error(err)
					return
				}
				if !createIndex.Acknowledged {
					// Not acknowledged ,创建失败
					log.Error("创建失败")
					return
				}
			}
			//插入文档
			req := es.EsClient.Bulk().Index(indexname)
			for _, o := range objects {
				b, err := json.Marshal(o)
				if err != nil {
					log.Error("json.Marshal failed:", err)
					continue
				}
				doc := elastic.NewBulkIndexRequest().Type("objects").Doc(string(b)).Id(o["ID"].(string))
				req.Add(doc)

			}
			if _, err := req.Do(ctx); err != nil {
				log.Error("插入失败" + err.Error())
				return
			}

		}
	}

}

//查询模式下的子对象
func GetObjectsBySchemeAndType(scheme string, objecttype string) ([]gorose.Data, error) {

	boolQ := elastic.NewBoolQuery()
	boolQ.Must(elastic.NewTermQuery("OBJECTSCEMA.keyword", scheme))
	boolQ.Must(elastic.NewTermQuery("OBJECTTYPE.keyword", objecttype))

	searchResult, err := es.EsClient.Search().
		Index(os.Getenv("ESINDEX")).
		Type("objects").         // 搜索的索引"objects"
		Query(boolQ).            // specify the query
		From(0).Size(999).       // 分页，单页显示999条
		Do(context.Background()) // 执行
	if err != nil {
		// Handle error
		log.Error("删除失败" + err.Error())
		return nil, err
	}
	if searchResult.Hits.TotalHits.Value > 0 {
		result := make([]gorose.Data, 0)
		for _, hits := range searchResult.Hits.Hits {

			d := make(gorose.Data)
			_ = json.Unmarshal(hits.Source, &d)
			d["id"] = d["ID"]
			d["NAME"] = d["OBJECTNAME"]
			d["TYPE"] = d["OBJECTTYPE"]

			result = append(result, d)
		}

		return result, nil
	}

	return nil, nil
}

//查询模式下按对象名的子对象
func GetObjectsBySchemeAndTypeAndName(scheme string, objecttype string, objectname string) (gorose.Data, error) {

	boolQ := elastic.NewBoolQuery()
	boolQ.Must(elastic.NewTermQuery("OBJECTSCEMA.keyword", scheme))
	boolQ.Must(elastic.NewTermQuery("OBJECTTYPE.keyword", objecttype))
	boolQ.Must(elastic.NewTermQuery("OBJECTNAME.keyword", objectname))
	searchResult, err := es.EsClient.Search().
		Index(os.Getenv("ESINDEX")).
		Type("objects").         // 搜索的索引"objects"
		Query(boolQ).            // specify the query
		From(0).Size(1).         // 分页，单页显示1条
		Do(context.Background()) // 执行
	if err != nil {
		// Handle error
		log.Error("删除失败" + err.Error())
		return nil, err
	}
	if searchResult.Hits.TotalHits.Value > 0 {

		hits := searchResult.Hits.Hits[0]

		d := make(gorose.Data)
		_ = json.Unmarshal(hits.Source, &d)
		d["id"] = d["ID"]
		d["NAME"] = d["OBJECTNAME"]
		d["TYPE"] = d["OBJECTTYPE"]

		return d, nil
	}

	return nil, nil
}

//搜索ddl
func GetObjectsByQueryString(queryString string, page int, pageSize int) ([]gorose.Data, int, error) {
	fmt.Println(os.Getenv("ESINDEX"))
	boolQ := elastic.NewBoolQuery()
	boolQ.Filter(elastic.NewWildcardQuery("DDL", "*"+queryString+"*"))
	searchResult, err := es.EsClient.Search().
		Index(os.Getenv("ESINDEX")).
		Type("objects").                      // 搜索的索引"objects"
		Query(boolQ).                         // specify the query
		From(page * pageSize).Size(pageSize). // 分页
		Do(context.Background())              // 执行
	if err != nil {
		// Handle error
		log.Error("查询失败" + err.Error())
		return nil, 0, err
	}
	if searchResult.Hits.TotalHits.Value > 0 {
		result := make([]gorose.Data, 0)
		for _, hits := range searchResult.Hits.Hits {

			d := make(gorose.Data)
			_ = json.Unmarshal(hits.Source, &d)
			d["id"] = d["ID"]
			d["NAME"] = d["OBJECTNAME"]
			d["TYPE"] = d["OBJECTTYPE"]
			d["DDL"] = ""

			result = append(result, d)
		}

		return result, int(searchResult.Hits.TotalHits.Value), nil
	}

	return nil, 0, nil
}
